﻿using System.Collections.Generic;

namespace IQIGame.Onigao.Logic
{
    //公式的操作符
    public class FormulaOperator
    {
        public enum OperatorType
        {

            /// <summary>
            /// 左括号:(,left bracket
            /// </summary>
            LB = 10,

            /// <summary>
            /// 右括号),right bracket
            /// </summary>
            RB = 11,

            /// <summary>
            /// 函数,function
            /// </summary>
            FUNC = 15,

            /// <summary>
            /// 逻辑非,!,NOT
            /// </summary>
            NOT = 20,

            /// <summary>
            /// 负号,-,negative sign
            /// </summary>
            NS = 22,

            /// <summary>
            /// pow运算,^
            /// </summary>
            POW = 23,

            /// <summary>
            /// 乘,*,multiplication
            /// </summary>
            MUL = 30,

            /// <summary>
            /// 除,/,division
            /// </summary>
            DIV = 31,

            /// <summary>
            /// 余,%,modulus
            /// </summary>
            MOD = 32,

            /// <summary>
            /// 加,+,Addition
            /// </summary>
            ADD = 40,

            /// <summary>
            /// 减,-,subtraction
            /// </summary>
            SUB = 41,

            /// <summary>
            /// 小于,less than
            /// </summary>
            LT = 50,

            /// <summary>
            /// 小于或等于,less than or equal to
            /// </summary>
            LE = 51,

            /// <summary>
            /// 大于,>,greater than
            /// </summary>
            GT = 52,

            /// <summary>
            /// 大于或等于,>=,greater than or equal to
            /// </summary>
            GE = 53,

            /// <summary>
            /// 等于,==,equal to
            /// </summary>
            ET = 60,

            /// <summary>
            /// 不等于!=,unequal to
            /// </summary>
            UT = 61,

            /// <summary>
            /// 逻辑与,&,AND
            /// </summary>
            AND = 70,

            /// <summary>
            /// 逻辑或,|,OR
            /// </summary>
            OR = 71,

            /// <summary>
            /// 逗号,comma
            /// </summary>
            CA = 80,

            /// <summary>
            /// 冒号,colon
            /// </summary>
            CO = 100,

            /// <summary>
            /// 问号,question
            /// </summary>
            QU = 101,


            // /// <summary>
            // /// 三元式，三目运算,Ternary
            // /// </summary>
            // TERNARY = 102,
        }

        //操作类型
        public OperatorType Type { get; private set; }

        //函数类型
        public int FuncType { get; private set; }

        private EFormulaFunctionType _EFuncType => (EFormulaFunctionType)this.FuncType;
        
        public FormulaOperator Initialize(OperatorType type)
        {
            this.Type = type;
            this.FuncType = (int)default;
            return this;
        }
        
        public FormulaOperator Initialize(OperatorType type, int funcType)
        {
            this.Type = type;
            this.FuncType = funcType;
            return this;
        }

        public void Reset()
        {
            this.FuncType = 0;
        }
        
        public override string ToString()
        {
            if (Type == OperatorType.FUNC)
            {
                return string.Format("Func:{0}", FuncType.ToString());
            }

            return Type.ToString();
        }

        public void TryFree()
        {
        }

        public static int ComparePriority(OperatorType optA, OperatorType optB)
        {
            if (optA == optB)
            {
                //A、B优先级相等
                return 0;
            }

            //乘,除,余(*,/,%)
            if ((optA >= OperatorType.MUL && optA <= OperatorType.MOD) &&
                (optB >= OperatorType.MUL && optB <= OperatorType.MOD))
            {
                return 0;
            }

            //加,减(+,-)
            if ((optA >= OperatorType.ADD && optA <= OperatorType.SUB) &&
                (optB >= OperatorType.ADD && optB <= OperatorType.SUB))
            {
                return 0;
            }

            //小于,小于或等于,大于,大于或等于(<,<=,>,>=)
            if ((optA >= OperatorType.LT && optA <= OperatorType.GE) &&
                (optB >= OperatorType.LT && optB <= OperatorType.GE))
            {
                return 0;
            }

            //等于,不等于(=,<>)
            if ((optA >= OperatorType.ET && optA <= OperatorType.UT) &&
                (optB >= OperatorType.ET && optB <= OperatorType.UT))
            {
                return 0;
            }

            if (optA < optB)
            {
                //A优先级高于B
                return 1;
            }

            //A优先级低于B
            return -1;
        }
    }
}